package com.yunjian.admin.config;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yunjian.core.basic.model.SDataDic;
import com.yunjian.core.basic.model.SDataDicKey;
import com.yunjian.core.basic.model.SUser;
import com.yunjian.core.basic.service.CacheListener;
import com.yunjian.core.basic.service.CacheService;
import com.yunjian.core.basic.service.SDataDicService;
import com.yunjian.core.basic.service.SUserService;
import com.yunjian.core.basic.vo.CacheType;
import com.yunjian.util.HttpUtil;
import com.yunjian.util.JsonUtil;

@Service
public class RMSCacheListener implements CacheListener{
	
	/**
	 * 用于标识本系统发出的请求
	 */
	public final static String RMS_SYS_FLAG = UUID.randomUUID().toString();
	
	private final static Logger logger = LoggerFactory.getLogger(RMSCacheListener.class);
	
	@Autowired
	private SDataDicService sDataDicService;
	@Autowired
	private CacheService cacheService;
	@Autowired
	private SUserService sUserService;
	
	@Override
	public void addCallback(String cacheName, Object key, Object value) {
		logger.debug("add cache:{} - key:{} - value:{}", cacheName, key, value);
	}

	@Override
	public void clearCallback(Collection<String> cacheNames) {
		logger.debug("clear all caches:{}", cacheNames);
		for (String cacheName : cacheNames) {
			updateRemoteCache(cacheName, null);
		}
	}

	@Override
	public void clearCallback(String cacheName, Object key) {
		logger.debug("clear cache:{} - key:{}", cacheName, key);
		// 清除shiro缓存
		if (CacheType.RMS_MENU.equals(cacheName) && key != null) {
			SUser user = sUserService.selectByPrimaryKey(key.toString());
			if (user != null) {
				cacheService.syncClearCache(cacheName, user); // 此方法不会再次产生回调，若使用cacheService.clearCache，则会产生死循环
			}
		}
		updateRemoteCache(cacheName, key);
	}
	
	/**
	 * 缓存事件更新至远程服务器
	 * @param cacheName
	 * @param key
	 */
	@SuppressWarnings("unchecked")
	protected void updateRemoteCache (String cacheName, Object key) {
		SDataDicKey dkey = new SDataDicKey();
		dkey.setDicGroup("SYS");
		dkey.setDicKey("CACHE_SYNC_UPDATE_REMOTE_CONFIG");
		SDataDic dic = sDataDicService.selectCacheByPrimaryKey(dkey);
		if (dic == null) {
			logger.error("未找到字典SYS-CACHE_SYNC_UPDATE_REMOTE_CONFIG，无法同步更新的缓存至远程服务器");
			return;
		}
		List<Map<String, Object>> remoteConfig = JsonUtil.jsonToList(dic.getDicValue());
		if (remoteConfig == null || remoteConfig.isEmpty()) {
			logger.info("未配置字典值-SYS-CACHE_SYNC_UPDATE_REMOTE_CONFIG，无需更新缓存至远程服务器");
			return;
		}
		for (Map<String, Object> remote : remoteConfig) {
			List<String> caches = (List<String>)remote.get("caches");
			String url = (String)remote.get("url");
			if (cacheName != null && (caches == null || ! caches.contains(cacheName))) {
				continue;
			}
			Map<String, String> params = new HashMap<String, String>();
			params.put("from", RMS_SYS_FLAG);
			params.put("cacheName", cacheName);
			if (key != null) {
				params.put("key", key.toString());
			}
			String res = HttpUtil.sendPost(url, params);
			if ("0000".equals(res)) {
				logger.info("缓存{}:key-{} 已同步更新至：{}", cacheName, key, url);
			} else {
				logger.info("缓存{}:key-{} 更新至远程服务器失败：{}", cacheName, key, url);
			}
		}
	}

}